using DocumentCreationSystem.Models;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.IO;

namespace DocumentCreationSystem.Services;

/// <summary>
/// 项目服务实现
/// </summary>
public class ProjectService : IProjectService
{
    private readonly IDataStorageService _dataStorage;
    private readonly ILogger<ProjectService> _logger;

    public ProjectService(IDataStorageService dataStorage, ILogger<ProjectService> logger)
    {
        _dataStorage = dataStorage;
        _logger = logger;
    }

    public async Task<Project> CreateProjectAsync(string name, string type, string rootPath, string? description = null)
    {
        try
        {
            // 确保项目路径存在
            if (!Directory.Exists(rootPath))
            {
                Directory.CreateDirectory(rootPath);
            }

            var project = new Project
            {
                Name = name,
                Type = type,
                RootPath = rootPath,
                Description = description,
                CreatedAt = DateTime.Now,
                UpdatedAt = DateTime.Now,
                Status = ProjectStatus.Active
            };

            project = await _dataStorage.CreateProjectAsync(project);

            // 初始化项目文件夹结构
            await InitializeProjectStructureAsync(rootPath, type);

            _logger.LogInformation($"创建项目成功: {name}");
            return project;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"创建项目失败: {name}");
            throw;
        }
    }

    public async Task<Project?> GetProjectAsync(int projectId)
    {
        var project = await _dataStorage.GetProjectAsync(projectId);
        return project?.Status != ProjectStatus.Deleted ? project : null;
    }

    public async Task<Project?> GetProjectByIdAsync(int projectId)
    {
        return await GetProjectAsync(projectId);
    }

    public async Task<Project?> GetProjectByPathAsync(string projectPath)
    {
        try
        {
            // 标准化路径以便比较
            var normalizedPath = Path.GetFullPath(projectPath).TrimEnd(Path.DirectorySeparatorChar);

            var projects = await _dataStorage.GetProjectsAsync();
            return projects.FirstOrDefault(p =>
                p.Status != ProjectStatus.Deleted &&
                Path.GetFullPath(p.RootPath).TrimEnd(Path.DirectorySeparatorChar).Equals(normalizedPath, StringComparison.OrdinalIgnoreCase));
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"根据路径获取项目失败: {projectPath}");
            return null;
        }
    }

    public async Task<List<Project>> GetAllProjectsAsync()
    {
        var projects = await _dataStorage.GetProjectsAsync();
        return projects
            .Where(p => p.Status != ProjectStatus.Deleted)
            .OrderByDescending(p => p.UpdatedAt)
            .ToList();
    }

    public async Task<bool> UpdateProjectAsync(Project project)
    {
        try
        {
            project.UpdatedAt = DateTime.Now;
            await _dataStorage.UpdateProjectAsync(project);
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"更新项目失败: {project.Id}");
            return false;
        }
    }

    public async Task<bool> DeleteProjectAsync(int projectId, bool deleteFiles = false)
    {
        try
        {
            var project = await GetProjectAsync(projectId);
            if (project == null)
                return false;

            // 标记为已删除
            project.Status = ProjectStatus.Deleted;
            project.UpdatedAt = DateTime.Now;

            await _dataStorage.UpdateProjectAsync(project);

            // 可选：删除物理文件
            if (deleteFiles && Directory.Exists(project.RootPath))
            {
                Directory.Delete(project.RootPath, true);
            }

            _logger.LogInformation($"删除项目成功: {project.Name}");
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"删除项目失败: {projectId}");
            return false;
        }
    }

    public async Task<NovelProject> CreateNovelProjectAsync(string projectName, string novelTitle, string creativeDirection, string rootPath)
    {
        try
        {
            // 先创建基础项目
            var project = await CreateProjectAsync(projectName, ProjectTypes.Novel, rootPath, $"小说项目: {novelTitle}");

            // 创建小说项目
            var novelProject = new NovelProject
            {
                ProjectId = project.Id,
                Title = novelTitle,
                CreativeDirection = creativeDirection,
                TargetChapterCount = 1000,
                TargetWordsPerChapter = 6500,
                Status = "Planning",
                CreatedAt = DateTime.Now,
                UpdatedAt = DateTime.Now
            };

            novelProject = await _dataStorage.CreateNovelProjectAsync(novelProject);

            _logger.LogInformation($"创建小说项目成功: {novelTitle}");
            return novelProject;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"创建小说项目失败: {novelTitle}");
            throw;
        }
    }

    public async Task<NovelProject?> GetNovelProjectAsync(int projectId)
    {
        return await _dataStorage.GetNovelProjectByProjectIdAsync(projectId);
    }

    public async Task<bool> UpdateNovelProjectAsync(NovelProject novelProject)
    {
        try
        {
            novelProject.UpdatedAt = DateTime.Now;
            await _dataStorage.UpdateNovelProjectAsync(novelProject);
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"更新小说项目失败: {novelProject.Id}");
            return false;
        }
    }

    public async Task<ProjectStatistics> GetProjectStatisticsAsync(int projectId)
    {
        var project = await GetProjectAsync(projectId);
        if (project == null)
            return new ProjectStatistics();

        var documents = await _dataStorage.GetDocumentsAsync(projectId);
        documents = documents.Where(d => d.Status == "Active").ToList();

        var stats = new ProjectStatistics
        {
            TotalDocuments = documents.Count,
            TotalWordCount = documents.Sum(d => d.WordCount),
            TotalFileSize = documents.Sum(d => d.FileSize),
            LastModified = documents.Any() ? documents.Max(d => d.UpdatedAt) : project.UpdatedAt,
            VectorizedDocuments = documents.Count(d => d.IsVectorized),
            PendingVectorization = documents.Count(d => !d.IsVectorized)
        };

        // 如果是小说项目，添加小说特有统计
        if (project.Type == ProjectTypes.Novel)
        {
            var novelProject = await GetNovelProjectAsync(projectId);
            if (novelProject != null)
            {
                var chapters = await _dataStorage.GetChaptersAsync(novelProject.Id);
                var characters = await _dataStorage.GetCharactersAsync(novelProject.Id);

                stats.TotalChapters = chapters.Count;
                stats.CompletedChapters = chapters.Count(c => c.Status == "Completed");
                stats.TotalCharacterCount = characters.Count;
                stats.CompletionPercentage = novelProject.TargetChapterCount > 0
                    ? (float)novelProject.CurrentChapterCount / novelProject.TargetChapterCount * 100
                    : 0;
            }
        }

        return stats;
    }

    public async Task<bool> InitializeProjectStructureAsync(string projectPath, string projectType)
    {
        try
        {
            // 创建基础文件夹（使用中文名称）
            var folders = new[] { "文档", "资源", "备份", "导出" };

            if (projectType == ProjectTypes.Novel)
            {
                // 只创建实际会使用的文件夹，避免创建空文件夹
                folders = folders.Concat(new[] {
                    "章节",     // 存放章节正文
                    "大纲",     // 存放各种大纲文件
                    "设定"      // 存放世界设定、角色设定等所有设定文件
                }).ToArray();
            }

            // 只创建基础文件夹，其他文件夹在实际需要时再创建
            foreach (var folder in folders)
            {
                var folderPath = Path.Combine(projectPath, folder);
                if (!Directory.Exists(folderPath))
                {
                    Directory.CreateDirectory(folderPath);
                }
            }

            // 创建项目配置文件
            var configPath = Path.Combine(projectPath, "project.json");
            var config = new ProjectConfig
            {
                DefaultDocumentFormat = "docx",
                AutoVectorize = true,
                ChunkSize = 500,
                ChunkOverlap = 50
            };

            if (projectType == ProjectTypes.Novel)
            {
                config.TargetWordsPerChapter = 6500;
                config.ConsistencyCheckInterval = 1000;
                config.AutoGenerateOutline = true;
                config.AutoUpdateCharacters = true;
            }

            await File.WriteAllTextAsync(configPath, JsonConvert.SerializeObject(config, Formatting.Indented));

            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"初始化项目结构失败: {projectPath}");
            return false;
        }
    }

    public async Task<bool> BackupProjectAsync(int projectId, string backupPath)
    {
        // TODO: 实现项目备份功能
        await Task.CompletedTask;
        return true;
    }

    public async Task<Project?> RestoreProjectAsync(string backupPath, string restorePath)
    {
        // TODO: 实现项目恢复功能
        await Task.CompletedTask;
        return null;
    }

    public bool IsValidProjectPath(string path)
    {
        try
        {
            return !string.IsNullOrWhiteSpace(path) && 
                   Path.IsPathFullyQualified(path) && 
                   !Path.GetInvalidPathChars().Any(path.Contains);
        }
        catch
        {
            return false;
        }
    }

    public async Task<ProjectConfig?> GetProjectConfigAsync(int projectId)
    {
        var project = await GetProjectAsync(projectId);
        if (project == null)
            return null;

        var configPath = Path.Combine(project.RootPath, "project.json");
        if (!File.Exists(configPath))
            return new ProjectConfig();

        try
        {
            var json = await File.ReadAllTextAsync(configPath);
            return JsonConvert.DeserializeObject<ProjectConfig>(json) ?? new ProjectConfig();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"读取项目配置失败: {projectId}");
            return new ProjectConfig();
        }
    }

    public async Task<bool> UpdateProjectConfigAsync(int projectId, ProjectConfig config)
    {
        try
        {
            var project = await GetProjectAsync(projectId);
            if (project == null)
                return false;

            var configPath = Path.Combine(project.RootPath, "project.json");
            var json = JsonConvert.SerializeObject(config, Formatting.Indented);
            await File.WriteAllTextAsync(configPath, json);

            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"更新项目配置失败: {projectId}");
            return false;
        }
    }
}
